#include <iostream>
using std::cout;
using std::endl;
/**
 * 这里X(int)不是构造，而是类型转换的函数，所以不加explicit
 * */

struct X{
    int i;


    X(int);
    X operator+(int);
};


struct Y{
    int i;


    Y(X);
    Y operator+(X);
    //类型转换运算符，返回值类型和函数名一样
    operator int();
};


extern X operator*(X,Y);
extern int f(X);


X x = 1;
Y y = x;
int i = 2;


int main() {
    cout << "x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;
    cout << "1: i + 10 = " << i+10 << endl;                          //(1)
    /**
     * Use of overloaded operator '+' is ambiguous:
     */
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "2: y + 10 = " << y+(X)10 << endl;                             //(2)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "3: y + 10 * y = " << y+(X)(10*(int)y) << endl;                    //(3)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    //没有把X转成int的，但是有转成Y的，而Y能转成int
    cout << "4: x + y + i = " << (Y)(x + y + i) << endl;          //(4)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "5: x * x + i = " << (Y)(x * x + i) << endl;          //(5)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "6: f(7) = " << f(7) << endl;               //(6)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "7: f(y) = " << f((X)y) << endl;               //(7)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "8: y + y = " << y+y << endl;                //(8)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;

    cout << "9: 10 + y = " << 10+y << endl;               //(9)
    cout << "now, x = " << (Y)x << ", " << "y = " << y << ", " << "i = " << i << endl;
    return 0;
}

X::X(int i) {
    this->i = i;
}

X X::operator+(int i) {
    this->i += i;
    return *this;
}

Y::Y(X xx) {
    this->i = xx.i;
}

Y Y::operator+(X xx) {
    this->i += xx.i;
    return *this;
}

Y::operator int() {
    return i;
}

X operator *(X xx, Y yy){
    xx.i *= yy.i;
    return xx;
}

int f(X xx){
    return xx.i;
}